﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace LCRReader
{
    public class Comm
    {
        SerialPort _serialPort = new SerialPort();
        public string LocalBuffer { get; set; }

        public bool isOpen { get { return _serialPort.IsOpen; } }

        public event Action<string> OnDataArrived;

        public static readonly Comm Inst = new Comm();

        private Comm()
        {
            _serialPort.DataReceived += SerialPort_DataReceived;
        }

        public static string[] getAvaliComms()
        {
            return SerialPort.GetPortNames();
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string line = _serialPort.ReadLine();
            LocalBuffer += line;
            if (OnDataArrived != null)
                OnDataArrived(LocalBuffer);
        }

        public bool Send(string CMD)
        {
            LocalBuffer = "";
            bool b;
            try
            {
                _serialPort.Write(CMD);
                b = true;
            }
            catch (Exception)
            {
                b = false;
                //  throw;
            }
            return b;
        }

        public int GetValue(string CMD, out float value)
        {
            try
            {
                Send(CMD + "\n");
                int iWait = 1;
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Restart();
                while (sw.ElapsedMilliseconds < (iWait * 1000))
                {
                    string pattern = @"[-+]?[0-9]*\.?[0-9]+";
                    var rgx = new System.Text.RegularExpressions.Regex(pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    var match = rgx.Match(LocalBuffer);
                    if (match.Success)
                    {
                        value = float.Parse(match.Value);
                        return 0;
                    }

                }
                value = float.NaN;
                return 1;
            }
            catch (Exception)
            {
                value = float.NaN;
                return -1;
            }
        }

        public bool Open(string COM, int Baudrate, int datebits, string stopbits, string parity)
        {
            bool open;
            try
            {
                if (_serialPort.IsOpen)
                    _serialPort.Close();
                _serialPort.PortName = COM;
                if (parity == "ODD")
                {
                    _serialPort.Parity = Parity.Odd;
                }
                else if (parity == "EVEN")
                {
                    _serialPort.Parity = Parity.Even;
                }
                else if (parity == "NONE")
                {
                    _serialPort.Parity = Parity.None;
                }
                _serialPort.BaudRate = Baudrate;
                if (stopbits == "1")
                {
                    _serialPort.StopBits = StopBits.One;
                }
                else if (stopbits == "1.5")
                {
                    _serialPort.StopBits = StopBits.OnePointFive;
                }
                else if (stopbits == "2")
                {
                    _serialPort.StopBits = StopBits.Two;
                }
                else if (stopbits == "0")
                {
                    _serialPort.StopBits = StopBits.None;
                }
                _serialPort.DataBits = datebits;

                _serialPort.Open();
                open = true;
            }
            catch (Exception)
            {
                open = false;
                //      throw;
            }
            return open;
        }

        bool Close()
        {
            Close();
            return true;
        }

    }
}
